package cc.rengu.igas.bomp.core.service.trans;

import cc.rengu.igas.bomp.common.constant.BompAppParamConstant;
import cc.rengu.igas.bomp.common.constant.BompTreeNodeConstant;
import cc.rengu.igas.bomp.common.dao.BompSequenceMapper;
import cc.rengu.igas.bomp.common.dao.MchntBaseInfoMapper;
import cc.rengu.igas.bomp.common.dao.QrCodeInfoMapper;
import cc.rengu.igas.bomp.common.dao.QrcodeBatchInfoMapper;
import cc.rengu.igas.bomp.common.dao.impl.BompSequenceMapperImpl;
import cc.rengu.igas.bomp.common.dao.impl.MchntBaseInfoMapperImpl;
import cc.rengu.igas.bomp.common.dao.impl.QrCodeInfoMapperImpl;
import cc.rengu.igas.bomp.common.dao.impl.QrcodeBatchInfoMapperImpl;
import cc.rengu.igas.bomp.common.entity.MchntBaseInfo;
import cc.rengu.igas.bomp.common.entity.QrCodeInfo;
import cc.rengu.igas.bomp.common.entity.QrcodeBatchInfo;
import cc.rengu.igas.bomp.common.enums.QrBindStatusEnum;
import cc.rengu.igas.bomp.common.enums.QrCodeTypeEnum;
import cc.rengu.igas.bomp.common.enums.QrStatusEnum;
import cc.rengu.igas.bomp.common.enums.RespCodeEnum;
import cc.rengu.igas.bomp.core.service.base.ManageService;
import cc.rengu.igas.bomp.facade.request.MchntQrCodeApplyRequest;
import cc.rengu.igas.bomp.facade.response.MchntQrCodeApplyResponse;
import cc.rengu.oltp.service.common.constant.AppConfigConstant;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.common.dao.SysParamMapper;
import cc.rengu.oltp.service.common.dao.impl.SysParamMapperImpl;
import cc.rengu.oltp.service.common.entity.SysParam;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.utility.util.*;

/**
 * 商户收款聚合码申请服务
 * Created by 王成 on 2018/7/19.
 * <p>
 * 聚合码：  银行域名 +  /inf=S   +  国密加密的系统流水号sysSeqNum
 * 银联码：  银联域名 + /银联机构号 +  /inf=S  +国密加密的系统流水号sysSeqNum
 * <p>
 * 处理流程：
 * 1、根据法人行(inst_id)查询系统参数表，获取二维码类型；
 * 2、判断二维码类型
 * 2.1 聚合码：
 * （1）根据法人行(inst_id)查询系统参数表，获取法人行的二维码域名
 * （2）调用加密平台加密系统流水号（sysSeqNum）
 * （3）拼接聚合码  规则：银行域名 +  /inf=S   +  国密加密的系统流水号sysSeqNum
 * （4）新增数据到二维码信息表
 * 2.2 银联码：
 * （1）常量：银联码域名
 * （2）根据法人行(inst_id)查询系统参数表，获取法人行在银联的机构号
 * （2）调用加密平台加密系统流水号（sysSeqNum）
 * （3）拼接聚合码  规则：银联域名  https://qr.95516.com/ + 银联机构号 +  /inf=S  +国密加密的系统流水号sysSeqNum
 * （4）新增数据到二维码信息表
 */
public class MchntQrCodeApplyService extends ManageService {

    /**
     * 交易金额来源 0-客户输入  1-固定金额
     */
    private static final String SRC_AMT_TYPE = "0";

    /**
     * 调用加密平台，类型：0-加密 1-解密
     */
    private static final String EdFuncFlag = "0";

    /**
     * 分隔符 /
     */
    private static final String NETWORK_SEPARATOR = "/";

    @Override
    protected Object bizBeforeCust() throws Exception {
        MchntQrCodeApplyRequest mchntQrCodeApplyRequest = new MchntQrCodeApplyRequest();
        ConvertUtil.convertOutput(mchntQrCodeApplyRequest);
        /* 参数合法性校验 */
        if (null == mchntQrCodeApplyRequest.getMchntNo()) {
            rglog.error("商户号不能为空!");
            throw new BizException(RespCodeEnum.MSG_VALID_CHECK_ERROR.getRespCode(), RespCodeEnum.MSG_VALID_CHECK_ERROR.getRespDesc());
        }

        return mchntQrCodeApplyRequest;
    }

    @Override
    protected BizResponse bizProcessCust(Object request) throws Exception {
        MchntQrCodeApplyRequest mchntQrCodeApplyRequest = (MchntQrCodeApplyRequest) request;
        String instId = mchntQrCodeApplyRequest.getHeader().getInstId();
        String mchntNo = mchntQrCodeApplyRequest.getMchntNo();
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String sysSeqNum = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM);
        BizResponse<MchntQrCodeApplyResponse> bizResponse = new BizResponse<>();

        StringBuilder qrCode = new StringBuilder();
        //获取二维码后缀，组装二维码域名
        String encyGenQrCodeSuffix = getEncyGenQrCode(instId, mchntNo, sysSeqNum, qrCode);

        /* 生成收款码,生成规则：银行域名 + /银联机构号/+inf=S +  */
        String mchntQrCode = qrCode + "inf=S" + encyGenQrCodeSuffix;
        rglog.debug("商户收款聚合码为:<{}>", mchntQrCode);

        MchntBaseInfo mchntBaseInfo = (MchntBaseInfo) xmlTreeUtil.getXmlTreeObjectValue(BompTreeNodeConstant.MCHNT_BASE_INFO, MchntBaseInfo.class);
        if (null == mchntBaseInfo) {
            MchntBaseInfoMapper mchntBaseInfoMapper = new MchntBaseInfoMapperImpl();
            mchntBaseInfo = mchntBaseInfoMapper.selectMchntBaseInfoByPrimaryKey(instId, mchntNo);
        }

        //插入二维码信息表
        insertMchntQrCodeInfo(mchntQrCodeApplyRequest, instId, mchntQrCode, encyGenQrCodeSuffix, mchntBaseInfo);

        /* 拼装返回信息 */
        bizResponse.setRspSysId(AppParamConstant.SYS_ID);
        MchntQrCodeApplyResponse mchntQrCodeApplyResponse = new MchntQrCodeApplyResponse();
        mchntQrCodeApplyResponse.setMchntQrCode(mchntQrCode);
        bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
        bizResponse.setResult(mchntQrCodeApplyResponse);
        return bizResponse;
    }

    private String getEncyGenQrCode(String instId, String mchntNo, String sysSeqNum, StringBuilder qrCode) throws Exception {
        /* 根据机构号获取二维码类型 */
        SysParamMapper sysParamMapper = new SysParamMapperImpl();
        SysParam instQrCodeTypeSysParam = sysParamMapper.selectSysParamByPrimaryKey(instId, BompAppParamConstant.MCHNT_PARAM_TYPE, BompAppParamConstant.INST_QRCODE_TYPE);
        if (null == instQrCodeTypeSysParam) {
            rglog.error("商户收款聚合码申请服务处理失败，根据机构号获取系统参数的二维码类型失败! instId:{}, mchntNo:{}", instId, mchntNo);
            throw new BizException(RespCodeEnum.GENERATE_MCHNT_QRCODE_ERROR.getRespCode(), RespCodeEnum.GENERATE_MCHNT_QRCODE_ERROR.getRespDesc());
        }

        if (QrCodeTypeEnum.CUPS.getCodeType().equals(instQrCodeTypeSysParam.getParamValue())) {
            //银联二维码域名 https://qr.95516.com/
            qrCode.append(BompAppParamConstant.CUPS_QRCODE_DOMAIN_NAME);

            /* 银联码，获取法人行在银联的机构号 */
            SysParam unionPayCode = sysParamMapper.selectSysParamByPrimaryKey(instId, BompAppParamConstant.MCHNT_PARAM_TYPE, BompAppParamConstant.CUPS_INSR_ID);
            if (null == unionPayCode) {
                rglog.error("商户收款聚合码申请服务处理失败！机构二维码类型为银联二维码，获取法人行在银联的机构号失败！instId:{},mchntNo:{}", instId, mchntNo);
                throw new BizException(RespCodeEnum.GENERATE_MCHNT_QRCODE_ERROR.getRespCode(), RespCodeEnum.GENERATE_MCHNT_QRCODE_ERROR.getRespDesc());
            }

            qrCode.append(unionPayCode.getParamKey()).append(NETWORK_SEPARATOR);
        } else if (QrCodeTypeEnum.IGAS.getCodeType().equals(instQrCodeTypeSysParam.getParamValue())) {
            //银行二维码域名
            SysParam bankDomainName = sysParamMapper.selectSysParamByPrimaryKey(instId, BompAppParamConstant.MCHNT_PARAM_TYPE, BompAppParamConstant.MCHNT_QRCODE_DOMAIN_NAME);
            if (null == bankDomainName) {
                rglog.error("商户收款聚合码申请服务处理失败！获取收款聚合码银行域名参数失败， instId:{},mchntNo:{}", instId, mchntNo);
                throw new BizException(RespCodeEnum.GENERATE_MCHNT_QRCODE_ERROR.getRespCode(), RespCodeEnum.GENERATE_MCHNT_QRCODE_ERROR.getRespDesc());
            }

            qrCode.append(bankDomainName.getParamValue());
            if (!bankDomainName.getParamValue().endsWith(NETWORK_SEPARATOR)) {
                qrCode.append(NETWORK_SEPARATOR);
            }
        }

        return sysSeqNum;
    }

    private void insertMchntQrCodeInfo(MchntQrCodeApplyRequest mchntQrCodeApplyRequest,
                                       String instId,
                                       String mchntQrCode,
                                       String encyData,
                                       MchntBaseInfo mchntBaseInfo) throws Exception {

        BompSequenceMapper bompSequenceMapper = new BompSequenceMapperImpl();
        //生成批次号
        String applyBatchSeqNum = bompSequenceMapper.getNextApplyBatchNo();
        if (null == applyBatchSeqNum) {
            rglog.error("批量申请收款聚合码服务处理失败，生成申请批次序号失败!");
            throw new BizException(RespCodeEnum.GENERATE_SEQ_NO_ERROR.getRespCode(), RespCodeEnum.GENERATE_SEQ_NO_ERROR.getRespDesc());
        }
        //yyyyMMdd+8位
        String applyBatchNo = DateUtil.getCurrentDate() + applyBatchSeqNum;


        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        /* 开启数据库事务 */
        String dbPoolName = XmlConfigUtil.getXmlConfigCacheKeyValue(AppConfigConstant.DATABASE_CONF_NODE, AppConfigConstant.MCMP_POOL_NAME);
        String corporation = xmlTreeUtil.getXmlTreeStringValue(AppParamConstant.CORPORATION);
        if (null != corporation && !corporation.isEmpty()) {
            String dbPoolCashNode = corporation.trim() + AppParamConstant.DATABASE_CONF_NODE;
            dbPoolName = XmlConfigUtil.getXmlConfigCacheKeyValue(dbPoolCashNode, AppConfigConstant.MCMP_POOL_NAME);
        }
        DbsUtil dbsUtil = new DbsUtil(dbPoolName);
        dbsUtil.dbsBeginTransaction();


        /* 登记商户收款聚合码信息 */
        QrCodeInfoMapper qrCodeInfoMapper = new QrCodeInfoMapperImpl();
        QrCodeInfo qrCodeInfo = new QrCodeInfo();
        qrCodeInfo.setId(RandomUtil.getUUID());
        qrCodeInfo.setInstId(instId);
        qrCodeInfo.setQrCodeType(QrCodeTypeEnum.IGAS.getCodeType());
        qrCodeInfo.setQrUrl(mchntQrCode);
        qrCodeInfo.setQrCode(encyData);
        //0-客户输入  1-固定金额
        qrCodeInfo.setSrcAmtType(SRC_AMT_TYPE);
        qrCodeInfo.setQrStatus(QrStatusEnum.NORMAL.getStatus());
        //已绑定
        qrCodeInfo.setBindStatus(QrBindStatusEnum.BINDED.getBindStatus());
        qrCodeInfo.setApplyBatchNo(applyBatchNo);

        qrCodeInfo.setMchntNo(mchntQrCodeApplyRequest.getMchntNo());
        qrCodeInfo.setChainMchntNo(mchntQrCodeApplyRequest.getChainMchntNo());
        qrCodeInfo.setOprId(mchntQrCodeApplyRequest.getUserId());
        String time = DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS");
        qrCodeInfo.setCreateTime(time);
        qrCodeInfo.setEffectiveTime(time);
        int iReturnCode = qrCodeInfoMapper.insertQrCodeInfoByTransaction(qrCodeInfo);
        if (0 != iReturnCode) {
            rglog.error("登记商户<{}> 二维码<{}>信息失败,iReturnCode:<{}>", mchntQrCodeApplyRequest.getMchntNo(), qrCodeInfo.getQrCode(), iReturnCode);
            throw new BizException(RespCodeEnum.REGISTER_QRCODE_INFO_ERROR.getRespCode(), RespCodeEnum.REGISTER_QRCODE_INFO_ERROR.getRespDesc());
        }

        QrcodeBatchInfo qrcodeBatchInfo = new QrcodeBatchInfo();
        qrcodeBatchInfo.setId(RandomUtil.getUUID());
        qrcodeBatchInfo.setQrCodeBatchNo(applyBatchNo);
        qrcodeBatchInfo.setInstId(instId);
        qrcodeBatchInfo.setQrCodeType(QrCodeTypeEnum.IGAS.getCodeType());
        qrcodeBatchInfo.setQrCodeBatchStatus("01");  //正式
        qrcodeBatchInfo.setCrtOrgId(mchntBaseInfo.getSignInstId());

        qrcodeBatchInfo.setOprId(mchntQrCodeApplyRequest.getUserId());
        qrcodeBatchInfo.setCreateTime(time);

        QrcodeBatchInfoMapper qrcodeBatchInfoMapper = new QrcodeBatchInfoMapperImpl();
        iReturnCode = qrcodeBatchInfoMapper.insertQrcodeBatchInfo(qrcodeBatchInfo);
        if (0 != iReturnCode) {
            rglog.error("登记二维码批次信息失败,iReturnCode:<{}>", qrcodeBatchInfo.getInstId(), iReturnCode);
            dbsUtil.dbsEndTransaction(false);
            throw new BizException(RespCodeEnum.REGISTER_QRCODE_INFO_ERROR.getRespCode(), RespCodeEnum.REGISTER_QRCODE_INFO_ERROR.getRespDesc());
        }

    }

    @Override
    protected void bizAfterCust(Object response) throws Exception {
        BizResponse bizResponse = (BizResponse) response;
        MchntQrCodeApplyResponse mchntQrCodeApplyResponse = (MchntQrCodeApplyResponse) bizResponse.getResult();
        ConvertUtil.convertInput(mchntQrCodeApplyResponse);
    }
}
